Github Actions是一个 CI/CD 工具,可以自动执行代码仓库中的任务,比如构建、测试和部署等。
一张图看懂 github actions 的工作流程:
它被定义在仓库的.github/workflows目录下,每个流程对应一个YAML文件。可以是.yml或.yaml后缀。
根据流程图我们可以知道需要定义一些关键性字段,我们以前端项目为例。定一个工作流在推送代码后执行构建。
任务触发器,监听到推送push事件后触发。定义执行的任务,最终执行构建.
拉取代码设置 node 环境安装依赖npm install执行脚本npm run build工作流文件命名为actions-test.yml,可以直接将内容复制到仓库的.github/workflows目录下,文件名可以自定义。保存后,点击仓库的Actions选项卡,即可看到该任务执行情况。:
on: [push]jobs: build-test:runs-on: ubuntu-lateststeps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 - run: npm install - run: npm run build在一个流程里可以配置多个任务,并行执行。任务之间也可以设置依赖关系,比如任务 A 执行完毕后,任务 B 才能开始。
也可以配置多个流程,并行执行。如果流程之间有依赖关系,则可以配置一个流程引用另一个流程,那么这个流程将会等待被引用的流程执行完毕后再执行。
基础语法包括 YAML 语法中使用的关键字及其作用。
name 工作流名称run-name 工作流运行的名称on 定义触发工作流的条件
可以设置单个或多个触发事件,或设置时间执行计划。还可针对执行设置限制,比如:特定分支、文件、标签等。
# 单个事件# on: push# 多个事件on: [push, pull_request, issues]只指定事件时,在事件的不同活动状态都会触发。有些事件没有活动类型,比如push,有些则有比如issues \ pull_request.
可以通过定义事件活动类型on..types,指定触发工作流事件的类型,比如新建 issue 触发,而不在编辑、删除时触发。
on: issues:types: opened某些事件还具有筛选器,筛选器定义在触发事件时,匹配了过滤器才执行,比如push可以配置筛选器branches \ branches-ignore,使其在特定分支推送时触发。
on: push:branches: - "main" - "releases/**"筛选器
branches \ branches-ignore可被用于push \ pull_request \ pull_request_target事件paths \ paths-ignore 可被用于push \ pull_request \ pull_request_target事件tags \ tags-ignore 可被用于push事件branches 指定分支,而branches-ignore 排除分支。不能同时使用,在使用branches可以使用!进行排除,并且必须包含一个不使用!的分支。
on: pull_request:- "releases/**"- "!releases/v1"paths 指定文件路径,而paths-ignore排除文件路径。
可以同时使用branches和paths,需要同时满足才会触发。
on: push:branches: - "main"paths: - "src/**"匹配定义模式可以使用符号* \ ** \ + \ ? \ !
而对于branches和tags的使用,它们是或的关系。代码推送或者有新的 tag 标签都会触发。
on: push:branches: - "main"tag: "*"permissions 定义工作流的操作权限。在修改仓库内容以及仓库设置等都需要设置操作权限。defaults 定义工作流中默认设置。比如定义执行脚本语言环境、执行脚本目录等。jobs 定义任务定义一个或多个任务。默认所有任务是并行的,可以通过jobs..needs指定任务依赖关系。
每个任务要在run-on指定的容器环境中运行。
jobs: build-test:runs-on: ubuntu-latestbuild-test就是定义的任务 id;ubuntu-latest就是runs-on指定的任务运行环境。
.name 任务名称.needs 指定任务依赖关系,必须完成依赖任务才能执行。依赖单个或多个任务。如果依赖的任务失败,则当前任务会跳过执行。
jobs: job1: job2:needs: job1 job3:needs: [job1, job2].if 满足条件时执行任务
可以使用上下文环境的变量或表达式,来指定任务是否执行。表达式需要使用${{}}语法,always()表示只要任务完成(不管成功与否),都执行任务。
jobs: job1: job2: job3:if: ${{ always() }}needs: [job1, job2].runs-on 任务运行环境
指定任务运行环境,可以是 github 提供的容器环境,或者自行托管的容器环境。个人开发者使用 github 提供的免费容器环境即可。
环境机器有 linux、windows 和 macOS 三种操作系统。
jobs: job1:runs-on: ubuntu-latest.env 定义可用于整个工作流或者单个步骤的变量。.steps 定义任务操作步骤
每个任务可以包含多个执行步骤,每个步骤都是在独立的进程中执行。所以步骤之间不会保留环境变量的更改。
通过以下字段定义步骤:
id 步骤 id,可以在上下文中引用步骤。name 步骤名称,uses 引用外部操作
选择作为步骤执行的外部操作引用。包括工作流、公共存储库或已发布的 docker 容器镜像中定义的操作。
这里我们只关注 github 提供的公共操作,actions/checkout@v4操作就是公共的用来检出仓库代码的操作。actions/setup-node@v4则是用来设置 node 环境。
jobs: build-test:runs-on: ubuntu-lateststeps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4run 执行命令用来执行脚本命令,比如run: npm install。可同时执行多个命令
- run: |npm installnpm run build当然,也可以分开两个步骤执行。如果执行的命令不在根目录下,还可以通过working-directory设置默认目录,如果想为所有run步骤设置默认目录,则可以在jobs..defaults.run中设置。
env 设置环境变量if 满足条件时执行步骤with 定义操作传入的传递参数
在使用操作actions/setup-node@v4时,指定 node 版本为 20.
jobs: build-test:runs-on: ubuntu-lateststeps: - uses: actions/checkout@v4with: node-version: "20"timeout-minutes 指定步骤执行超时时间.timeout-minutes 指定任务执行超时时间可以看到有些配置字段一样,但它们所在的作用域不一样。所以文件特别注重书写,根据层级缩进来定义配置字段。注意键值对之间必须要有空格
除了上述列出的常见配置字段,还有一些特殊配置,比如workflow_call定义工作流的输入和输出;.outputs定义任务输出,可以在另一个任务里使用;.strategy可以定义在多个策略下的版本或者系统里运行任务。
使用变量除了执行操作,还可以使用上下文环境提供的变量。比如前面使用过的always()表达式,不管依赖的任务执行是否成功,都会执行当前任务。
jobs: job1: job2:needs: job1 job3:if: ${{ always() }}needs: [job1, job2]默认环境变量默认环境变量由 GitHub 设置,不能直接被工作流访问,但是可以通过所处的上下文可访问变量访问这些变量。这些以GITHUB_*和RUNNER_*开头的变量,不可以覆盖这些变量。
GITHUB_* 可以由上下文变量github.*访问;RUNNER_* 可以由上下文变量runner.*访问。
GITHUB_ACTION 运行的操作名称 github.actionGITHUB_ACTION_PATH 运行的操作路径 github.action_pathGITHUB_ACTOR 发起工作流程的个人或应用程序名称 github.actorGITHUB_EVENT_NAME 触发的工作流事件名称 github.event_nameRUNNER_OS 运行操作系统的名称 runner.osRUNNER_ARCH 运行操作系统的架构 runner.arch等等 可以查看详细的变量说明
下面的工作流会输出当前操作名称,因为我们没有定义操作name,会输出__run
on: push:jobs: build-test:runs-on: ubuntu-lateststeps: - run: echo ${{ github.action }}自定义变量定义自己的变量,可以使用env字段。每个部分都可以定义自己的变量,比如整个工作流、某个任务、某个步骤。
envjobs..envjobs..steps[*].env变量命名规则:包含字母、数字、下划线,不允许空格。不能以数字开头。不区分大小写。
on: push:env: name: hbootjobs: build-test:runs-on: ubuntu-latestenv: age: 18steps: - run: echo "Say $val to $name. you are $age "env: val: hello除了直接通过$访问变量外,还可以通过上下文变量evn访问。比如env.name,此时则需要使用${{}}包裹,有些情况下必须这样访问,比如使用if表达式。
表达式之前已经使用过always()表达式。表达式一般用来条件判断,常与if字段结合使用。
通过${{}}对表达式求值。假值(false \ 0 \ -0 \ "" \ '' \nul)都会被转为 false;
evn: isSave: ${{ "" }} isSame: ${{ null }}可以通过运算符进行求值,比如> \ < \ >= \ git tag v0.0.2# 推送到仓库$> git push origin v0.0.2
为了保证我们每次发送的版本都是固定的下载地址,我们发布时固定 tag 为latest。 指定 actions 入参tag_name: latest
- name: create github release uses: softprops/action-gh-release@v2.0.8 with:tag_name: latestname: ${{github.ref_name}}比较实用的 actions